#include <stdlib.h>
#include <stdio.h>
#include "myFramework.h"
#include "LoadModel.h"

Image *g_img = NULL;
Texture *g_texture = NULL, *g_texRT = NULL;
RenderTarget *g_renderTarget = NULL;
Mesh *g_model = NULL;
Camera *g_rtCamera = NULL;

APP_MAIN_IMPLEMENTATION(LoadModel)

void LoadModel::Render2D(double timeElapsed)
{
}

void LoadModel::Render(double timeElapsed)
{
  if(!g_renderTarget)
    return;

  m_renderer->EnableTexture();
  m_renderer->EnableDepthTest();

  //rotate the camera for the fbo rendering
  static float rotate = 0.0f;
  glm::vec3 pos = glm::vec3( sinf(rotate)*3.f, 5.f, cosf(rotate)*3.f);
  rotate = (rotate + 0.003f);

  // render to fbo
  g_renderTarget->Begin();
  g_rtCamera->LookAt(pos, glm::vec3(0,0,0));
  g_rtCamera->Look();
  m_renderer->Clear(WHITE);

  DrawGrid(BLACK);

  m_renderer->EnableTexture();
  m_renderer->EnableDepthTest();
  g_texture->Begin();

  g_model->Render(timeElapsed);

  g_renderTarget->End();
  //g_renderTarget->Download("LoadModel.bmp");

  static int count = 0;
  if(count == 30)
  {
    g_renderTarget->Download("test.bmp");
  }
  else
    count++;

  // now render to the real frame buffer
  m_renderer->Clear(BLACK);
  m_camera->Look();

  m_shaderProgram->Begin();
  m_shaderProgram->SetShaderParam("ModelView", m_camera->GetMatrixModelView());
  m_shaderProgram->SetShaderParam("Projection", m_camera->GetMatrixProjection());
  m_shaderProgram->SetShaderParam("EyePosition", m_camera->GetEye());
  m_sky->SetTexture(g_texture);
  m_sky->Render(timeElapsed);

  m_shaderProgram->End();

  DrawGrid(WHITE);
  glColor3f(1,1,1);

  glDisable(GL_LIGHTING);
  g_texRT->Begin();

  DrawCube();

  g_texRT->End();
}

LoadModel::LoadModel()
{
  
}

void LoadModel::InitApp()
{ 
  NATIVE_APP::InitApp();

  // load a texture for model
  //g_img = ImageManager::InstanceRef().LoadFromFile("img1", "axis.jpg");
  g_img = ImageManager::InstanceRef().LoadFromFile("img1", "Sky_horiz_10_4096.jpg");
  g_texture = m_renderer->CreateTexture();
  g_texture->Create(*g_img);

  // create a texture for fbo
  g_texRT = m_renderer->CreateTexture(Texture::MIPMAP_DYNAMIC);
  g_texRT->Create(512, 512, PIXEL_R8G8B8A8);

  // create fbo as a render target, and bind a texture to it
  g_renderTarget = m_renderer->CreateRenderTarget();
  g_renderTarget->Create(g_texRT);

  // load a model
  g_model = MeshManager::InstanceRef().LoadObj("model1", "teapot.obj");

  // create a extra camera for fbo
  g_rtCamera = m_renderer->CreateCamera();

  g_renderer->EnableTexture();
  m_sky = new SkyDome();
  m_sky->SetTexture(g_texture);

  m_shaderProgram = ShaderProgram::CreateFromFile("normal.glsl.vs", "normal.glsl.ps");
}

// save fbo to a image while pressing "c"
bool LoadModel::OnKey(unsigned key, bool down)
{
  if(down && key == KEY_C)
  {
    static int count = 0;
    std::stringstream ss;
    ss << "screen" << count++ << ".png";

    Image* imgOutput = ImageManager::InstanceRef().CreateImage(EMPTY_STRING, g_texRT->GetWidth(), g_texRT->GetHeight(), PIXEL_R8G8B8A8);
    g_renderTarget->Download(imgOutput);
    ImageManager::InstanceRef().SaveToFile(imgOutput, ss.str() , IFF_PNG);
  }

  return NATIVE_APP::OnKey(key, down);
}

LoadModel::~LoadModel()
{
  delete m_sky;
}
